home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 2 / Meeting Pearls Vol. II (1995)(GTI - Schatztruhe)[!].iso / Pearls / dev / Oberon4Amiga / ETH_Tools / Find.Mod (.txt) < prev    next >
Oberon Text  |  1994-10-21  |  7KB  |  183 lines

  1. Syntax10.Scn.Fnt
  2. FoldElems
  3. Syntax10i.Scn.Fnt
  4. Syntax10b.Scn.Fnt
  5. MODULE Find;    (* HM 10 Nov 93 *)
  6. IMPORT Display, Files, Oberon, Viewers, MenuViewers, TextFrames, Texts;
  7. CONST
  8.     stdMenu = "System.Close  System.Copy  System.Grow  Edit.Search  Edit.Store ";
  9.     File = POINTER TO FileDesc;
  10.     FileDesc = RECORD
  11.         name: ARRAY 32 OF CHAR;
  12.         next: File
  13.     END;
  14.     file: File;
  15.     w: Texts.Writer;
  16.     out: Texts.Text;
  17. PROCEDURE ScanPar (VAR s: Texts.Scanner);    
  18.     VAR v: Viewers.Viewer; t: Texts.Text; beg, end, time: LONGINT;
  19. BEGIN
  20.     Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(s);
  21.     IF (s.class = Texts.Char) & (s.c = "^") THEN
  22.         Oberon.GetSelection(t, beg, end, time);
  23.         IF time >= 0 THEN
  24.             Texts.OpenScanner(s, t, beg); Texts.Scan(s)
  25.         END
  26. END ScanPar;
  27. PROCEDURE OpenViewer(name: ARRAY OF CHAR; t: Texts.Text);    
  28.     VAR v: MenuViewers.Viewer; x, y: INTEGER; t1: Texts.Text; menu: TextFrames.Frame; buf: Texts.Buffer;
  29. BEGIN
  30.     IF Files.Old("Edit.Menu.Text") = NIL THEN menu := TextFrames.NewMenu(name, stdMenu)
  31.     ELSE menu := TextFrames.NewMenu(name, "");
  32.         NEW(t1); Texts.Open(t1, "Edit.Menu.Text");
  33.         NEW(buf); Texts.OpenBuf(buf); Texts.Save(t1, 0, t1.len, buf); Texts.Append(menu.text, buf)
  34.     END;
  35.     Oberon.AllocateUserViewer(0, x, y);
  36.     v := MenuViewers.New(menu, TextFrames.NewText(t, 0), TextFrames.menuH, x, y)
  37. END OpenViewer;
  38. PROCEDURE Search (fn: ARRAY OF CHAR; pat: ARRAY OF CHAR; m: INTEGER);    
  39.     CONST
  40.         bufSize = 31744; (*2**15 - 1024*)
  41.         CR = 0DX; TAB = 09X;
  42.         textTag = 496; oldTextTag = -4095;
  43.         f: Files.File; r: Files.Rider;
  44.         n, pos: LONGINT;
  45.         i, j, i0: INTEGER;
  46.         ch, patj: CHAR;
  47.         found: BOOLEAN;
  48.         tab: ARRAY 265 OF SHORTINT;
  49.         text: ARRAY bufSize OF CHAR;
  50. BEGIN
  51.     (*----- open file *)
  52.     f := Files.Old(fn);
  53.     IF f = NIL THEN RETURN END;
  54.     Files.Set(r, f, 0); Files.ReadInt(r, i);
  55.     IF (i = textTag) OR (i = oldTextTag) THEN
  56.         pos := 0; (*Files.ReadLInt(r, pos); -- modified to search also in collapsed Fold segments*)
  57.         (*----- initialize tab *)
  58.         Texts.WriteString(w, "--- "); Texts.WriteString(w, fn); Texts.WriteLn(w);
  59.         FOR i := 0 TO 255 DO tab[i] := SHORT(m) END;
  60.         FOR i := 0 TO m-2 DO tab[ORD(pat[i])] := SHORT(m - i - 1) END;
  61.         patj := pat[m-1]; found := FALSE;
  62.         LOOP
  63.             (*----- read text[0..n-1] *)
  64.             n := Files.Length(f) - pos;
  65.             IF n > bufSize THEN n := bufSize END;
  66.             IF n < m THEN EXIT END;
  67.             Files.Set(r, f, pos); Files.ReadBytes(r, text, n);
  68.             (*----- search pat in text[0..n-1] *)
  69.             i := m - 1; j := i;
  70.             WHILE i < n DO
  71.                 IF text[i] = patj THEN i0 := i;
  72.                     REPEAT DEC(i); DEC(j) UNTIL (j < 0) OR (text[i] # pat[j]);
  73.                     IF j < 0 THEN
  74.                         (*------ found: print result *)
  75.                         found := TRUE;
  76.                         WHILE (i >= 0) & (text[i] # CR) & (text[i] >= TAB) DO DEC(i) END;
  77.                         INC(i);
  78.                         Files.Set(r, f, pos + i);
  79.                         REPEAT Files.Read(r, ch); Texts.Write(w, ch); INC(i) UNTIL (ch = CR) OR (ch < TAB) OR (r.eof)
  80.                     ELSE i := i + tab[ORD(text[i])]
  81.                     END;
  82.                     IF i <= i0 THEN i := i0 + 1 END;
  83.                     j := m - 1
  84.                 ELSE i := i + tab[ORD(text[i])]
  85.                 END
  86.             END;
  87.             pos := pos + i - m + 1
  88.         END;
  89.         IF found THEN Texts.WriteLn(w); Texts.Append(out, w.buf) ELSE Texts.OpenWriter(w) END
  90.     ELSE
  91.         Texts.WriteString(w, fn); Texts.WriteString(w, " is no text file"); Texts.WriteLn(w);
  92.         Texts.Append(Oberon.Log, w.buf)
  93. END Search;
  94. (* -- commands -- *)
  95. PROCEDURE Domain*;    (* {filename} ~ *)    
  96.     VAR s: Texts.Scanner; f, last: File;
  97. BEGIN file := NIL; last := NIL;
  98.     ScanPar(s);
  99.     WHILE s.class = Texts.Name DO
  100.         NEW(f); f.next := NIL;
  101.         IF last = NIL THEN file := f ELSE last.next := f END;
  102.         last := f;
  103.         COPY(s.s, f.name);
  104.         Texts.Scan(s);
  105.         WHILE (s.class = Texts.Char) & (s.c = "/") DO Texts.Scan(s); Texts.Scan(s) END
  106. END Domain;
  107. PROCEDURE All*;    (* ^ *)    
  108.     VAR pat: ARRAY 128 OF CHAR; m: INTEGER; f: File;
  109.     PROCEDURE ReadPattern (VAR pat: ARRAY OF CHAR; VAR m: INTEGER);    
  110.         VAR t: Texts.Text; r: Texts.Reader; beg, end, time: LONGINT; ch: CHAR;
  111.     BEGIN
  112.         Oberon.GetSelection(t, beg, end, time);
  113.         IF time > 0 THEN
  114.             Texts.OpenReader(r, t, beg); m := 0;
  115.             WHILE beg < end DO Texts.Read(r, ch);
  116.                 IF m < 127 THEN pat[m] := ch END;
  117.                 INC(m); INC(beg)
  118.             END;
  119.             pat[m] := 0X
  120.         END;
  121.     END ReadPattern;
  122. BEGIN
  123.     ReadPattern(pat, m);
  124.     out := TextFrames.Text("");
  125.     OpenViewer(pat, out); f := file;
  126.     WHILE f # NIL DO
  127.         Search(f.name, pat, m);
  128.         f := f.next
  129. END All;
  130. PROCEDURE Diff*;    (*- compares two texts from the last two selections; sets selection to first difference *)    
  131.     VAR f1, f2: TextFrames.Frame; p1, p2: LONGINT; r1, r2: Texts.Reader; ch1, ch2: CHAR;
  132.     PROCEDURE GetSelection(VAR F: TextFrames.Frame; VAR pos: LONGINT);    
  133.         VAR time: LONGINT; v: Viewers.Viewer; x: INTEGER; f: Display.Frame;
  134.     BEGIN
  135.         time := -1; x := 0; F := NIL;
  136.         WHILE x < Display.Width DO
  137.             v := Viewers.This(x, 0);
  138.             WHILE v.state > 1 DO
  139.                 f := v.dsc.next;
  140.                 WITH f: TextFrames.Frame DO
  141.                     IF f.hasSel & (f.time > time) THEN F := f; pos := f.selbeg.pos; time := f.time END
  142.                 ELSE
  143.                 END;
  144.                 v := Viewers.Next(v)
  145.             END;
  146.             x := x + v.W
  147.         END;
  148.         IF F # NIL THEN TextFrames.RemoveSelection(F); TextFrames.RemoveCaret(F) END
  149.     END GetSelection;
  150.     PROCEDURE ShowSelection(f: TextFrames.Frame; pos: LONGINT);    
  151.         VAR x: LONGINT;
  152.     BEGIN
  153.         IF pos > TextFrames.Pos(f, f.X + f.W - 1, f.Y) THEN 
  154.             x := pos - 150; IF x < 0 THEN x := 0 END;
  155.             TextFrames.Show(f, x)
  156.         END;
  157.         TextFrames.SetSelection(f, pos, pos+1)
  158.     END ShowSelection;
  159. BEGIN
  160.     GetSelection(f1, p1); GetSelection(f2, p2);
  161.     IF (f1 # NIL) & (f2 # NIL) THEN
  162.         Texts.OpenReader(r1, f1.text, p1); 
  163.         Texts.OpenReader(r2, f2.text, p2); 
  164.         REPEAT
  165.             Texts.Read(r1, ch1); INC(p1); Texts.Read(r2, ch2); INC(p2);
  166.         UNTIL (ch1 # ch2) OR (ch1 = 0X);
  167.         IF (ch1 = 0X) OR (ch2 = 0X) THEN DEC(p1); DEC(p2) END;
  168.         ShowSelection(f1, p1-1); ShowSelection(f2, p2-1)
  169. END Diff;
  170. BEGIN
  171.     file := NIL; Texts.OpenWriter(w)
  172. END Find.
  173. (*--------------------------------------------------------------------------
  174. Find.Domain ~
  175.     Specify the files in which Find.All should search for a pattern.
  176. Find.All ^
  177.     Searches the selection in the files specified with Find.Domain.
  178.     Lists all lines containing the pattern.
  179. Find.Diff ^
  180.     Compares two texts starting from the two most recent selections
  181.     Sets new selections at the first position where the two texts differ.
  182. --------------------------------------------------------------------------*)
  183.